/***
 * ExecutableCmd
 * Representation and manipulation of an executable command
 * Created 14/06/04
 * Contact: Fabienne.Boyer@imag.fr
 * Author: fabienne Boyer
 * 
 * 06/07/04 Daniel Hagimont completion of the integration in Jade2
 */

package fr.jade.util;



public class ShellCommand
{
	private static Runtime runtime = Runtime.getRuntime();
	
	/**
	 * execute a command asynchronously
	 * don't redirect stdout or stderr
	 * @throws JadeException if the execution failed
	 */    
	public static ShellCommand asyncExec(String cmd, String envp[])
	throws JadeException
	{
		try {
			Process process = runtime.exec(cmd, envp);
			return new ShellCommand(cmd, process);
		} catch (Exception e) {
			throw new JadeException("ShellCommand: cannot execute cmd " + cmd, e);
		}
	}

	/**
	 * execute the command synchronously
	 * redirect both stdout and stderr 
	 * @throws JadeException if the execution failed
	 */    
	public static void syncExec(String cmd, String envp[])
	throws JadeException
	{
		try {
			ShellCommand shcmd = asyncExec(cmd, envp);
			shcmd.forwardAll();
			shcmd.process.waitFor();
		} catch (Exception e) {
			throw new JadeException("ShellCommand: cannot execute cmd " + cmd, e);
		}
	}
	
	public String command;
	public Process process;
	public StreamForwarder outFwder;
	public StreamForwarder errFwder;
	
	private ShellCommand(String command, Process process)
	{
		this.command = command;
		this.process = process;
	}
	
	public void forwardStdoutAndWaitForString(String prefix, String wantedStr)
	throws JadeException
	{
		if (outFwder!=null)
			return;
		
		outFwder = new StreamForwarder(
				prefix,
				process.getInputStream(),
				System.out
		);
		if (wantedStr!=null)
			outFwder.prepareWaitForString(wantedStr);
		outFwder.start();
		if (wantedStr!=null)
			outFwder.waitForString();
	}
	
	public void forwardStdout(String prefix)
	throws JadeException
	{
		forwardStdoutAndWaitForString(prefix, null);
	}

	public void forwardStdoutAndWaitForString(String wantedStr)
	throws JadeException
	{
		forwardStdoutAndWaitForString("[" + command + "] out> ", wantedStr);
	}
	
	public void forwardStdout()
	throws JadeException
	{
		forwardStdoutAndWaitForString(null);
	}
	
	public void forwardStderr(String prefix)
	{
		if (errFwder!=null)
			return;
		
		errFwder = new StreamForwarder(
				prefix,
				process.getErrorStream(),
				System.err
		);
		errFwder.start();
	}
	
	public void forwardStderr()
	throws JadeException
	{
		forwardStderr("[" + command + "] err> ");
	}
	
	public void forwardAll(String prefix)
	throws JadeException
	{
		forwardStdout(prefix);
		forwardStderr(prefix);
	}

	public void forwardAll()
	throws JadeException
	{
		forwardStdout();
		forwardStderr();
	}
}
